package com.pervasive.geoTagging;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

import android.content.SharedPreferences.Editor;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.RadioGroup.LayoutParams;
	
public class MappaActivity extends MapActivity implements LocationListener{


	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try{
        	map = new MapView(this,"0s7c-5KfwMp_6huYv2gpHIJAMU8Ouv5HejILi9g");
        	map.setClickable(true);
        	map.setId(10);
        	map.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        	setContentView(map);
	        overlays = map.getOverlays();
	        controller = map.getController();
	        map.setBuiltInZoomControls(true);
	        geocoder = new Geocoder(this);
	        cl =  new DefaultHttpClient();
	        Drawable d;
			String type = MainActivity.pref.getString(PreferencesActivity.MARKER, "rosso");
			if(type.equals("rosso")) d = getResources().getDrawable(R.drawable.marker);
			else if(type.equals("giallo")) d = getResources().getDrawable(R.drawable.marker3);
			else d = getResources().getDrawable(R.drawable.marker2);
			markerList = new MarkerList(MappaActivity.this, getApplicationContext(), d, map, cl);
			//GeoPoint g = new GeoPoint(40000, 40000);
			//markerList.addOverlayItem(g, "Benevento, Italia", "");
			//overlays.add(markerList);
			//map.invalidate();
        }catch(Exception e){ }
    }

	private void loadMarker(HttpClient cl){
		String citta = MainActivity.pref.getString(ALBUM_LIST, ""), location = null;
    	StringTokenizer tokenizer = new StringTokenizer(citta);
    	try{
        	while((location = tokenizer.nextToken("%")) != null){
				location = location.replace(" ", "+");
				HttpResponse res = cl.execute(new HttpGet("http://maps.googleapis.com/maps/api/geocode/xml?address="+location+"&sensor=false"));
				ByteArrayOutputStream outstream = new ByteArrayOutputStream();
				res.getEntity().writeTo(outstream);
				ByteArrayInputStream instream = new ByteArrayInputStream(outstream.toByteArray());
				DocumentBuilder bulder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
				Document document = bulder.parse(new InputSource(new InputStreamReader(instream, "UTF-8")));
				Element geocodeResponse = document.getDocumentElement();
				Element result = (Element)geocodeResponse.getElementsByTagName("result").item(0);
				Element geometry = (Element)result.getElementsByTagName("geometry").item(0);
				Element locationTag = (Element)geometry.getElementsByTagName("location").item(0);
				Element lat = (Element)locationTag.getElementsByTagName("lat").item(0);
				String latitude = lat.getFirstChild().getNodeValue();
				Element lng = (Element)locationTag.getElementsByTagName("lng").item(0);
				String longitude = lng.getFirstChild().getNodeValue();
				double latPoint = Double.parseDouble(latitude);
				double lngPoint = Double.parseDouble(longitude);
				markerList.addOverlayItem(new GeoPoint((int)(latPoint*1E6), (int)(lngPoint*1E6)), location.replace("+", " "), "");
        	}
    	}catch(Exception e){ }
	}

	public void onResume(){
		if(MainActivity.pref.contains(ALBUM_LIST)) loadMarker(cl);
	    if(markerList.size() > 0)
	    	overlays.add(markerList);
	    lm = (LocationManager)getSystemService(LOCATION_SERVICE);
	    lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
	    Location l = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
	    if(l != null){
		   Double latitude = l.getLatitude()*1E6;
		   Double longitude = l.getLongitude()*1E6;
		   GeoPoint you = new GeoPoint(latitude.intValue(), longitude.intValue());
		   locationOverlay = new LocationOverlay(you);
		   overlays.add(locationOverlay);
		   controller.setCenter(you);
		   controller.setZoom(8);
	    }else{
	    	Double latitude = Double.parseDouble(MainActivity.pref.getString("Latitude", "0"))*1E6;
			Double longitude = Double.parseDouble(MainActivity.pref.getString("Latitude", "0"))*1E6;
			GeoPoint you = new GeoPoint(latitude.intValue(), longitude.intValue());
			locationOverlay = new LocationOverlay(you);
			overlays.add(locationOverlay);
			controller.setCenter(you);
			controller.setZoom(8);
	    }
	    map.postInvalidate();
	    super.onResume();
	}
	
	public void onPause(){
		super.onPause();
		Editor edit = MainActivity.pref.edit();
		//edit.putString(ALBUM_LIST, cityList).commit();
		edit.putString("Latitude", locationOverlay.getLatitude()+"").commit();
		edit.putString("Longitude", locationOverlay.getLongitude()+"").commit();
		super.onPause();
	}
	
	public void onDestroy(){
		super.onDestroy();
		lm.removeUpdates(this);
	}

	public void onBackPressed(){
		super.onBackPressed();
		try{
			MarkerList.balloonView = null;
		}catch(NullPointerException e){ }
	}

	protected boolean isRouteDisplayed() {
		return false;
	}
	
	public void onProviderEnabled(String provider) {
		if (provider.equals(LocationManager.GPS_PROVIDER)) {
	           lm.removeUpdates(this);
	           lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,this);
	    }
	}
	
	public void onStatusChanged(String arg0, int arg1, Bundle arg2) { }
	
	public void onProviderDisabled(String arg0) {
		if(arg0.equals(LocationManager.GPS_PROVIDER))
				lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
	}
	
	public void onLocationChanged(Location arg0) {
		 overlays.remove(locationOverlay);
		 Location l = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
	     Double latitude = l.getLatitude()*1E6;
	     Double longitude = l.getLongitude()*1E6;
	     GeoPoint you = new GeoPoint(latitude.intValue(), longitude.intValue());
	     overlays.remove(locationOverlay);
	     overlays.add((locationOverlay = new LocationOverlay(you)));
	     map.postInvalidate();
	     controller.setCenter(you);
   }

	protected static void addLocation(String location){
		if(!cityList.contains(location)){
			cityList = new String(cityList.concat(location).concat("%"));
			MainActivity.pref.edit().putString(ALBUM_LIST, cityList).commit();
		}
	}
	
	protected static void removeLocation(String location){
		location=location.replace("+", " ");
		if(!cityList.contains(location)){
			cityList = cityList.replace(location+"%", "");
			MainActivity.pref.edit().putString(ALBUM_LIST, cityList).commit();
		}
	}
	
	protected static String getCurrentLocation() throws IOException{
		List<Address> address = geocoder.getFromLocation(locationOverlay.getLatitude(), locationOverlay.getLongitude(), 1);
		if(address.size() != 0)
			return address.get(0).getLocality()+", "+address.get(0).getCountryName().toLowerCase();
		return null;
	}
	
	private static Geocoder geocoder;
	private MapController controller;
	private static LocationOverlay locationOverlay;
	private LocationManager lm;
	private MapView map;
	private List<Overlay> overlays;
	private MarkerList markerList;
	private HttpClient cl;
	private static final String ALBUM_LIST = "album";
	private static String cityList = "";
}